package org.swizframework.util
{

	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.managers.CursorManager;
	import mx.rpc.AsyncToken;
	import mx.rpc.IResponder;
	import mx.rpc.events.ResultEvent;
	
	/**
	 * 
	 * @author soenkerohde
	 * 
	 */	
	public class TestUtil
	{
		
		
		/**
		 * addAsync can be used from TestCases which want to rest an
		 * asynchronous action (service call which returns AsyncToken)
		 * 
		 * Usage from TestCase:
		 * 
		 * function testLogin():void
		 * {
		 * 		TestUtil.addAsync(this, userDelegate.loginUser("foo", "bar"), onLogin, 5000);
		 * }
		 * 
		 * @param tc The TestCase itself from which this is called
		 * @param token The AsyncToken returned by the service-/delegate-call
		 * @param callback function to call in the testcase when operation is complete
		 * @param delay time to wait until the call is considered a failure
		 * 
		 */		
		public static function addAsync(testCase:Object, token:AsyncToken, callback:Function, delay:Number):void
		{
			var responder:TestResponder = new TestResponder();
			token.addResponder(responder);
			// this has changed from addAsync, because I am now using fluint
			responder.addEventListener(ResultEvent.RESULT, testCase.asyncHandler(callback, delay));
		}
		
		/**
		 * mockResult can be used from mocked delegate
		 * a delegate method call generally returns an async token
		 * which is the result of a service call.
		 * 
		 * Usage from mocked Delegate:
		 * 
		 * function loginUser(username:String, password:String):AsyncToken
		 * {
		 * 		return TestUtil.mockResult(<user username="testUser" />, 1000);
		 * }
		 * 
		 * @param result
		 * @param delay
		 * @param showBusyCursor
		 * @return 
		 * 
		 */		
		public static function mockResult(result:Object, delay:Number = 500, showBusyCursor:Boolean = true):AsyncToken
		{
			return mockResultEvent(new ResultEvent(ResultEvent.RESULT, false, true, result), delay, showBusyCursor);
		}
		
		/**
		 * @param resultEvent ResultEvent for IResponder
		 * @param delay in ms
		 * @param showBusyCursor to indicate pending with BusyCursor
		 * @return AsyncToken
		 * 
		 */		
		public static function mockResultEvent(resultEvent:ResultEvent, delay:Number = 500, showBusyCursor:Boolean = true):AsyncToken
		{
			if(showBusyCursor)
			{
				CursorManager.setBusyCursor();
			}
			var token:AsyncToken = new AsyncToken(null);
			var t:Timer = new Timer(delay, 1);
			t.addEventListener(TimerEvent.TIMER_COMPLETE, function(event:TimerEvent):void
			{
				for each(var responder:IResponder in token.responders)
				{
					responder.result(resultEvent);
				}
				t = null;
				token = null;
				if(showBusyCursor)
				{
					CursorManager.removeBusyCursor();
				}
			});
			t.start();
			return token;
		}
		

	}
}